﻿//
// This file is part of AVSReflector project
// Copyright (C) 2011 Yuan Pengfei
//

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using AVSReflector.Core;

namespace AVSReflector
{
    public partial class Reflector : Form
    {
        Sequence[] data;
        Bitmap[] images;
        IReflector owner;
        Picture currentPicture;
        int SelX, SelY;

        public Reflector(IReflector o, Sequence[] d)
        {
            InitializeComponent();
            owner = o;
            data = d;

            tv.BeginUpdate();
            for (int i = 0; i < data.Length; ++i)
                AddNode(data[i], tv.Nodes);
            tv.EndUpdate();
        }

        private void Reflector_FormClosed(object sender, FormClosedEventArgs e)
        {
            owner.ReflectorClose();
        }

        private void playToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (images == null)
            {
                List<Bitmap> l = new List<Bitmap>();
                Picture prev = null;
                bool first = true;
                for (int i = 0; i < data.Length; ++i)
                {
                    for (int j = 0; j < data[i].children.Length; ++j)
                    {
                        if (!data[i].children[j].GetType().IsSubclassOf(typeof(Picture)))
                            continue;
                        Picture p = (Picture)data[i].children[j];
                        if (p.picture_type == 2)
                            l.Add(p.ImageRGB);
                        else
                        {
                            if (first)
                            {
                                first = false;
                                l.Add(p.ImageRGB);
                            }
                            else
                            {
                                if (prev != null)
                                    l.Add(prev.ImageRGB);
                                prev = p;
                            }
                        }
                    }
                }
                if (prev != null)
                    l.Add(prev.ImageRGB);
                images = l.ToArray();
            }
            Player player = new Player(images);
            player.Show();
        }

        private void expandToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tv.ExpandAll();
        }

        private void collapseToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tv.CollapseAll();
        }

        private void tv_AfterSelect(object sender, TreeViewEventArgs e)
        {
            INode n = ((CustomTreeNode)e.Node).node;
            BoxText.Text = null;
            status.Text = null;
            SelX = -1;
            SelY = -1;
            if (n.GetType().IsSubclassOf(typeof(Picture)) || n.GetType() == typeof(Slice))
            {
                Picture p = null;
                if (n.GetType() == typeof(Slice))
                    p = (Picture)(((CustomTreeNode)e.Node.Parent).node);
                else
                    p = (Picture)n;
                currentPicture = p;
                BoxBlock.Image = p.ImageBlock;
                BoxRGB.Image = p.ImageRGB;
                BoxY.Image = p.ImageY;
                BoxCb.Image = p.ImageCb;
                BoxCr.Image = p.ImageCr;
                BoxText.Lines = n.GetInfo();
                return;
            }
            currentPicture = null;
            BoxBlock.Image = null;
            BoxRGB.Image = null;
            BoxY.Image = null;
            BoxCb.Image = null;
            BoxCr.Image = null;
            BoxText.Lines = n.GetInfo();
        }

        static string FormatName(string name)
        {
            StringBuilder sb = new StringBuilder(name);
            for (int i = 1; i < sb.Length; ++i)
                if (sb[i] >= 'A' && sb[i] <= 'Z')
                    sb.Insert(i++, " ");
            return sb.ToString();
        }

        void AddNode(INode n, TreeNodeCollection c)
        {
            TreeNode tn = new CustomTreeNode(FormatName(n.GetType().Name), n);
            if (n.GetType() == typeof(Sequence))
            {
                Sequence s = (Sequence)n;
                for (int i = 0; i < s.children.Length; ++i)
                    AddNode(s.children[i], tn.Nodes);
            }
            if (n.GetType() == typeof(IPicture))
            {
                IPicture p = (IPicture)n;
                for (int i = 0; i < p.children.Length; ++i)
                    AddNode(p.children[i], tn.Nodes);
            }
            if (n.GetType() == typeof(BPicture))
            {
                BPicture p = (BPicture)n;
                for (int i = 0; i < p.children.Length; ++i)
                    AddNode(p.children[i], tn.Nodes);
            }
            if (n.GetType() == typeof(PPicture))
            {
                PPicture p = (PPicture)n;
                for (int i = 0; i < p.children.Length; ++i)
                    AddNode(p.children[i], tn.Nodes);
            }
            c.Add(tn);
        }

        private void BoxBlock_MouseClick(object sender, MouseEventArgs e)
        {
            if (currentPicture == null)
                return;
            SelX = e.X / 15;
            SelY = e.Y / 15;
            BoxBlock.Invalidate();
            BoxText.Lines = currentPicture.BlockMatrix[SelY, SelX].GetInfo();
        }

        private void BoxBlock_MouseLeave(object sender, EventArgs e)
        {
            if (currentPicture == null)
                return;
            status.Text = "";
        }

        private void BoxBlock_MouseMove(object sender, MouseEventArgs e)
        {
            if (currentPicture == null)
                return;
            int x = e.X / 15;
            int y = e.Y / 15;
            status.Text = "(" + x + ", " + y + ")";
        }

        private void BoxBlock_Paint(object sender, PaintEventArgs e)
        {
            if (SelX < 0)
                return;
            int x = SelX, y = SelY;
            Pen pen;
            pen = new Pen(Color.White);
            Graphics g = e.Graphics;
            g.DrawLine(pen, x * 15, y * 15, x * 15 + 14, y * 15);
            g.DrawLine(pen, x * 15, y * 15, x * 15, y * 15 + 14);
            g.DrawLine(pen, x * 15 + 14, y * 15 + 14, x * 15 + 14, y * 15);
            g.DrawLine(pen, x * 15 + 14, y * 15 + 14, x * 15, y * 15 + 14);
        }

        private void BoxRGB_MouseMove(object sender, MouseEventArgs e)
        {
            if (currentPicture == null)
                return;
            int x = e.X / 16;
            int y = e.Y / 16;
            status.Text = "(" + x + ", " + y + ")  (" + e.X + ", " + e.Y + ")";
        }

        private void BoxRGB_MouseLeave(object sender, EventArgs e)
        {
            if (currentPicture == null)
                return;
            status.Text = "";
        }

        private void BoxRGB_MouseClick(object sender, MouseEventArgs e)
        {
            try
            {
                if (currentPicture == null)
                    return;
                SelX = e.X / 16;
                SelY = e.Y / 16;
                BoxText.Lines = currentPicture.BlockMatrix[SelY, SelX].GetInfo();
            }
            catch (System.Exception) { }
        }
    }
}
